package nku.csc364;

/**
 * 
 * Raj Akula
 * CSC 365 Assignment 5
 * 
 * THe Main class to build 8 hash tables and run finds on them and output the
 * times for each of the find loops. 
 *
 *Running the find 10,000,000 times on each hash table gave the most consistent
 *results.
 */

import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Random;

public class Main {
	private static final String dbFile = "datafile.txt";
	
	
	public static void main(String args[]) {
		int recordSize=0;
		
		String[] ssnArray = new String[500];  //guaranteed < 500 records in file.
		ArrayList<AbstractHashTable> hashTableList= new ArrayList<AbstractHashTable> (8);
		try{
			recordSize = loadSsnArray(ssnArray);
			//Create the 8 hashtables
			for (double d = .4d; d <= 1.0d; d += .2d) {
				DoubleHashingHashTable hashTable = new DoubleHashingHashTable(recordSize,d);
				loadFileToHashTable(hashTable);
				hashTableList.add(hashTable);
				
				SeparateChainingHashTable schashTable = new SeparateChainingHashTable(recordSize,d);
				loadFileToHashTable(schashTable);
				hashTableList.add(schashTable);
			}
			
			//8 Hash tables are loaded.
			runFinds(hashTableList, ssnArray, recordSize);
			
		}catch (Exception e){
			System.out.println ("Sorry , unable to read the data file");
			
		}
		
	}
	
	/**
	 * 
	 * 
	 * Runs the finds on the hashtables and outputs the results of
	 * all 8 hashtable finds.
	 * 
	 */
	private static void runFinds(ArrayList<AbstractHashTable> hashTableList, String[] ssnArray, int recordSize){
		Random rand = new Random();
		int counter=1;
		ArrayList<Integer> outputValues=new ArrayList<Integer>(8);
		for (AbstractHashTable hTable : hashTableList){
			// System.out.println ("Processing table " + counter);
			
			long start = System.currentTimeMillis();
			for (int i=0; i < 1000000; i++){
				int key=rand.nextInt(recordSize);
				Object obj=hTable.find(ssnArray[key]);
			}
			
			outputValues.add((int)(System.currentTimeMillis()-start));
			// System.out.println ("Done with hashtable  " + counter);
			counter ++;
		}
		
		printResults(outputValues);
		
		
		
	
	}
	
	private static void printResults(ArrayList<Integer> outputValues){
		
		System.out.println ("\tDouble Hashing Hashtable\tSeparate Chaining Hashtable");
		System.out.println ("Load Factor 0.4\t\t" + outputValues.get(0) + "\t\t\t" + outputValues.get(1));
		System.out.println ("Load Factor 0.6\t\t" + outputValues.get(2) + "\t\t\t" + outputValues.get(3));
		System.out.println ("Load Factor 0.8\t\t" + outputValues.get(4) + "\t\t" + outputValues.get(5));
		System.out.println ("Load Factor 1.0\t\t" + outputValues.get(6) + "\t\t" + outputValues.get(7));
		
	}

	
	/**
	 * Load the SSNs from the file into a array. 
	 * And return the number of records loaded
	 */
	private static int loadSsnArray(String[] ssnArray)throws IOException {
		BufferedReader input = new BufferedReader(
				new FileReader(dbFile));

		String line = null; // not declared within while loop
		int idx=0;
		while ((line = input.readLine()) != null) {
			String[] lineArray = line.split("\t");
			ssnArray[idx]=lineArray[2];
			idx++;
		}
		return idx;
	}

	/**
	 * Given the hashtable , load the contents of the file into it
	 * creating a Person object from each record of the file and using the
	 * SSN field as the key in the hashtable.
	 */
	private static void loadFileToHashTable(AbstractHashTable ht)
			throws IOException {

		int arrayIdx = 0;

		BufferedReader input = new BufferedReader(
				new FileReader(dbFile));

		String line = null; // not declared within while loop
		while ((line = input.readLine()) != null) {
			String[] lineArray = line.split("\t");
			Person person = new Person(lineArray[1], lineArray[0],
					lineArray[2], lineArray[3], lineArray[4].charAt(0),
					lineArray[5]);

			ht.insert(person.getSsn(), person);

		}

	}
}
